#ifndef _CMD_SOCKET_H_
#define _CMD_SOCKET_H_

#include <limits.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <thread>

#include <sys/socket.h>
#include <netinet/in.h>

#include <AudioMessager.h>

#define USING_INET_SOCKET

#ifdef USING_UNIX_DOMAIN_SOCKET
#define BOSE_CMD_SOCKET_MODE (0666)
#define SOCKIDTYPE char *
#elif defined(USING_INET_SOCKET)
#define SOCKIDTYPE int
#endif

#define MAX_BOSECMD_LISTEN_CLIENT_Fd_NUM (255)
#define MAX_BUFF_SIZE (1024 * 1024 * 16)

#define ERROR_SOCKET_CLOSED (-1035)


#define MAX_CMD_LEN (1024)


typedef int (*CommandProcessorFuncType)(const char * cmdStr, char* const response, int);

typedef struct {
    void* pThis;
    CommandProcessorFuncType handler;
    int socketFd;
    
} threadArgType;

namespace com {
namespace bose {

class CmdSocket {
public: 
    int isExiting;
    virtual ~CmdSocket();
    CmdSocket(SOCKIDTYPE id);
    //get socket fd
    int get_service_fd() { return serverFd;}

static int send_data(int fd, const char * buffer, int max_len);
static int receive_data(int fd, const char * buffer, int max_len);

protected:
    virtual int processing() = 0;
    int serverFd;  //server socket FD
    const SOCKIDTYPE mId;

private:
    CmdSocket() = delete;
};

class CmdSocketServer : public CmdSocket {
public:
    CmdSocketServer(SOCKIDTYPE id, CommandProcessorFuncType handler, int flag);
    ~CmdSocketServer(){}
    int startProcess(){return processing();}
    int exec_send_once(int clientFd, CommandProcessorFuncType handler);

    int service_listen();
    int getFlag(){return mDefaultFlag;}
    int proccess_play(const char * str, char* const outData, int maxBuffSize);
    AudioMessager* mAm;

protected:
    virtual int processing();
    const CommandProcessorFuncType mHandler;
    const int mDefaultFlag;
    
private:
    CmdSocketServer() = delete;
};

class CmdSocketClient : public CmdSocket {
public:
    //connect to server
    int connect_server(const char * path);

protected:
    int clientFd;
};

} //namespace bose
} //namespace com
#endif